﻿using HelperFromTheSkeleton.Common;
using HelperFromTheSkeleton.JwtHelper;
using HelperFromTheSkeleton.Model.APICoreModels;
using HelperFromTheSkeleton.Model.RequestModels;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json.Linq;
using System.IdentityModel.Tokens.Jwt;
using System.Reflection;
using System.Security.Claims;

namespace HelperFromTheSkeleton.APICore.Filters
{
    public class APICoreActionFilter : IActionFilter
    {
        private AccessLogModel _accessLogModel;

        public APICoreActionFilter()
        {
            _accessLogModel = new AccessLogModel();
        }


        public void OnActionExecuting(ActionExecutingContext context)
        {
            _accessLogModel = new AccessLogModel
            {
                RequestData = context.ActionArguments.ToJson()
            };
            ControllerBase? controllerBase = context.Controller as ControllerBase;
            if (controllerBase != null)
            {
                ClaimsPrincipal user = controllerBase.User;
                string text = controllerBase.Request.Headers.Authorization.ToString();
            }
            List<Claim> source = context.HttpContext.User.Claims.ToList();
            _accessLogModel.UserID = source.FirstOrDefault((Claim m) => m.Type == "UserID")?.Value;
            _accessLogModel.Route = context.HttpContext.Request.Path.Value ?? "";
            List<string?> list = context.HttpContext.Request.Headers.Authorization.ToList();
            if (list == null || list.Count <= 0)
            {
                return;
            }

            string[]? array = list[0]?.Split(' ');
            if (array == null || array.Length <= 1)
            {
                return;
            }

            object? service = context.HttpContext.RequestServices.GetService(typeof(JwtManage));
            JwtManage? jwtManage = default;
            int num;
            if (service != null)
            {
                jwtManage = service as JwtManage;
                num = ((jwtManage != null) ? 1 : 0);
            }
            else
            {
                num = 0;
            }

            if (num != 0)
            {
                if (jwtManage == null)
                {
                    throw new InvalidOperationException("");
                }
                string text2 = array[1];
                SecurityToken securityToken = new JwtSecurityTokenHandler().ReadToken(text2);
                JwtSecurityToken? jwtSecurityToken = securityToken as JwtSecurityToken;
                if (jwtSecurityToken != null)
                {
                    jwtManage!.Token = jwtSecurityToken;
                }
                jwtManage!.TokenString = text2;
            }
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            ObjectResult? objectResult = context.Result as ObjectResult;
            if (objectResult != null)
            {
                ResultModel? resultModel = objectResult.Value as ResultModel;
                if (resultModel != null)
                {
                    Type type = resultModel.GetType();
                    _accessLogModel.ResponseData = objectResult.Value?.ToJson();
                }
            }
            else if (!(context.Result is JsonResult))
            {
            }
            if (context.Exception != null)
            {
                _accessLogModel.ExceptionText = context.Exception!.Message;
                string message = _accessLogModel.ToJson();
                (Config.GetServer<ILoggerFactory>()?.CreateLogger("AccessLog"))?.LogError(message);
            }
            else
            {
                string message2 = _accessLogModel.ToJson();
                (Config.GetServer<ILoggerFactory>()?.CreateLogger("AccessLog"))?.LogInformation(message2);
            }
        }
    }
}
